/**
 * @class Restautant
 * @method build 初始化
 * @method addProcess(ele,idx) 添加进度条颜色
 * @member config 配置文件
 *
 * cook
 * @method toggleCookPlus() 显示加号
 * @method hireCook() 雇佣厨师
 * @method missCook(id) 解雇厨师
 * @member cooksEle cooks元素
 * @member cookPlusEle 增加厨师按钮
 * @member cooks 所有可用厨师
 * @member cooksOnServe 在工作的厨师数量
 * @member cookDefaultEle 默认厨师元素
 * @member cookEleArr 所有厨师元素数组
 * @member cooksOnServe 在工作的厨师数量
 *
 * customer
 * @method addCustom() 增加顾客
 * @method delCustom(cus) 删除顾客
 * @method saveMenu() 保存菜单
 * @member customersEle customers元素
 * @member customersWaitEle 等待队列元素
 * @member customers 所有客户数组
 * @member customersId 当前客户ID
 * @member customerDefaultEle 客户默认模板
 * @member customerEleArr 在服务客户元素数组
 * @member foodWaitQueue 没有分配厨师的餐
 *
 */

class Restautant {
  constructor(config) {
    this.config = config;
    // cooks
    this.cooksEle = document.getElementById('cooks');
    this.cookPlusEle = document.getElementById('cookPlus');
    this.cooks = [];
    this.cooksOnServe = 0;
    // customer
    this.customersEle = document.getElementById('customers');
    this.customersWaitEle = document.getElementById('customerWaiting');
    this.customers = [];
    this.customersId = 0;
    this.foodWaitQueue = [];
  }

  build() {
    // cookEle

    this.cookDefaultEle = document
      .getElementById('cookDefault')
      .cloneNode(true);
    this.cookDefaultEle.classList.remove('delSit');
    this.cookDefaultEle.removeAttribute('id');
    // eslint-disable-next-line
    for (let i = 0; i < this.config.cookMax; i++) {
      const cook = this.cookDefaultEle.cloneNode(true);
      cook.classList.add('delSit');
      this.cooksEle.insertBefore(cook, this.cookPlusEle);
      // eslint-disable-next-line
      this.cooks.push(new Cook(i, cook));
    }
    document.getElementById('cookDefault').remove();
    this.cookEleArr = this.cooksEle.children;

    this.customerDefaultEle = document
      .getElementById('curtomerDefault')
      .cloneNode(true);
    this.customerDefaultEle.removeAttribute('id');
    // eslint-disable-next-line
    for (let i = 0; i < this.config.customerMax; i++) {
      const customer = this.customerDefaultEle.cloneNode(true);
      this.customersEle.appendChild(customer);
    }
    this.customerDefaultEmptyEle = this.customerDefaultEle.cloneNode(true);
    this.customerDefaultEle.classList.remove('delPeople');
    document.getElementById('curtomerDefault').remove();
    this.customerEleArr = this.customersEle.children;

    // cookPlus
    bind(this.cookPlusEle, 'click', () => {
      this.hireCook();
    });

    const t = [...this.cookEleArr];
    t.pop();
    t.forEach((d, i) => {
      bindLongTouch(
        d,
        () => {
          restaurant.missCook(i);
        },
        () => {
          if (this.cooks[i].serveFor && this.cooks[i].timer) {
            this.cooks[i].timer.speedUp(restaurant.config.cookSpeedUpRate);
          }
        },
      );
    });

    this.state = new StateManager(document.getElementById('stat'));
    this.state.today = 0;
    this.state.money = this.config.initMoney;
    this.timer = new GameTimer();
    this.timer.startAll();

    new MsgBox({
      title: '餐厅开业啦!',
      text: `WebMOOC餐厅即将开业,请认真经营你的餐厅吧, 经营餐厅需要做好下面的几件事情, 加油!<br>
        点击加号招募厨师<br>
        长按厨师解雇厨师<br>
        在厨师做菜时双击厨师加速烹饪<br>
        为顾客点单<br>
        <strong>由于作者记错了大作业提交时间(记成2022.01.20), 开发的比较仓促简陋, 在娱乐之前最好先看看开发文档,或者在DevTool中查看游戏说明与参数配置</strong><br>
      `,
      btns: [
        {
          title: '看看开发文档',
          work: () => {
            window.open(
              'https://baidu.liukairui.cc/class-ending-homework/pro/document',
              '_blank',
            );
          },
        },
        {
          title: '开始经营吧',
          work() {},
        },
      ],
    });
  }

  // public style
  addProcess(
    ele,
    idx = Number.parseInt(Math.random() * this.config.colors.length, 10) %
      this.config.colors.length,
  ) {
    const pro =
      ele.querySelector('.face .process') || ele.querySelector('.process');
    this.config.colors.forEach((d) => {
      pro.classList.remove(d);
    });
    pro.classList.add(this.config.colors[idx]);
    return idx;
  }

  // cook
  toggleCookPlus() {
    this.cookPlusEle.classList.toggle('delSit');
  }

  hireCook() {
    const cook = this.cooks.find((d) => !d.onServe);
    if (!cook) return false;
    new MsgBox({
      title: '招聘新厨师',
      text: `招聘一名新厨师可以帮你更快的为顾客烹饪菜肴, 增加餐厅收入. 
      你最多可以拥有${restaurant.config.cookMax}名厨师<br>
      但每个厨师每周需要你支付工资${restaurant.config.weeklySalary}元<br>
      请问你确认招聘一名新厨师吗?`,
      btns: [
        {
          title: '是的, 确认招聘',
          work: () => {
            // eslint-disable-next-line
            if (++this.cooksOnServe === this.cooks.length)
              this.toggleCookPlus();
            cook.work();
          },
        },
        {
          title: '先不了',
          work() {},
        },
      ],
    });
    return true;
  }

  missCook(id) {
    const cook = this.cooks[id];
    if (cook.onServe === false) return false;
    let salary =
      restaurant.config.severancePay +
      (cook.workTime * restaurant.config.severancePay) / 7;
    if (salary > restaurant.state.money) {
      new AlertBox(
        `解雇这位厨师需要支付解雇费与工资合计${salary}元, 而你的钱钱不够(*′口')`,
        2000,
        'error',
      );
    } else {
      new MsgBox({
        title: '解雇厨师',
        text: `解雇当前闲置的厨师可以帮你节省成本<br>
        解雇时会按照厨师本周已经工作的日子结算工资, 并会赔偿一周工资作为违约金.<br>
        解雇当前厨师结算工资和解约金需要付出${salary}元 <br> gie gie 你真的要解雇他吗?`,
        btns: [
          {
            title: '继续解雇',
            work: () => {
              if (!cook.rest())
                return new AlertBox(
                  '厨师正在工作, 无法解雇(人家都在工作你还要解雇人家￣へ￣)',
                  1000,
                  'error',
                );
              else new AlertBox(`解雇成功`, 1000, 'error');
              restaurant.state.money -= salary;
              // eslint-disable-next-line
              if (this.cooksOnServe-- === restaurant.cooks.length)
                this.toggleCookPlus();
            },
          },
          {
            title: '取消',
            work() {},
          },
        ],
      });
    }

    return true;
  }

  // customer
  addCustom() {
    if (
      this.customers.length >=
      this.config.customerMax + this.config.customerWaitMax
    ) {
      // eslint-disable-next-line
      new AlertBox('一名顾客因为等待区已满离开了...', 1000, 'error');
      return false;
    }
    // eslint-disable-next-line
    const custom = new Customer(this.customersId++);
    this.customers.push(custom);
    return true;
  }

  delCustom(cus) {
    cus.flashIndex();
    this.customers.splice(cus.onWaitIdx, 1);
    if (cus.onWaitIdx >= this.config.customerMax) {
      cus.ele.remove();
    } else {
      this.customersEle.replaceChild(
        this.customerDefaultEmptyEle.cloneNode(true),
        cus.ele,
      );
      if (this.customers[restaurant.config.customerMax - 1]) {
        this.customers[restaurant.config.customerMax - 1].buildDom();
      }
    }
    this.customerEleArr = this.customersEle.children;
  }

  saveMenu(customer, arr) {
    const cookAvaileble = this.cooks.filter((d) => d.onServe && !d.cooking);
    arr.forEach((d, i) => {
      if (i < cookAvaileble.length) {
        cookAvaileble[i].toCooking(this.config.foods[d], customer);
      } else {
        this.foodWaitQueue.push({
          customer,
          foodId: d,
        });
      }
    });
    customer.addRecept(arr);
  }
}
